home *** CD-ROM | disk | FTP | other *** search
- //===========================================================================
- // Custom Solution Wizard - Visual C++ Shell - Sample Functions
- //
- //---------------------------------------------------------------------------
- // These files were created with the MFC AppWizard to illustrate how the
- // sample NSLearningNetwork and NSRecallNetwork classes can be used to
- // interact with a Custom Solution Wizard generated DLL for training
- // or recall from a Visual C++ program.
- //---------------------------------------------------------------------------
- // This program will compile and run without any further modification.
- // It uses the training data taken from your original breadboard. This data
- // was saved to two files: InputData.txt and DesiredData.txt during the DLL
- // generation.
- //===========================================================================
-
- //===========================================================================
- // Includes
- //===========================================================================
- #include "stdafx.h"
- #include <string.h>
- #include "VCPPShell.h"
- #include "NSNetwork.h"
- #include "Globals.h"
-
- //===========================================================================
- // Debug handling generated by MFC AppWizard.
- //===========================================================================
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
-
- //===========================================================================
- //===========================================================================
- // CLASS: CVCPPShellApp
- //===========================================================================
- //===========================================================================
-
- //===========================================================================
- // Global declaration of application generated by MFC AppWizard.
- //===========================================================================
- CVCPPShellApp theApp;
-
- //===========================================================================
- // CLASS: CVCPPShellApp MESSAGE MAP
- //---------------------------------------------------------------------------
- // Note: This mapping was built by the MFC AppWizard.
- //===========================================================================
- BEGIN_MESSAGE_MAP(CVCPPShellApp, CWinApp)
- //{{AFX_MSG_MAP(CVCPPShellApp)
- // NOTE - the ClassWizard will add and remove mapping macros here.
- // DO NOT EDIT what you see in these blocks of generated code!
- //}}AFX_MSG
- ON_COMMAND(ID_HELP, CWinApp::OnHelp)
- END_MESSAGE_MAP()
-
- //===========================================================================
- // CLASS: CVCPPShellApp FUNCTION: <constructor>()
- //---------------------------------------------------------------------------
- // Note: This function was built by the MFC AppWizard.
- //===========================================================================
- CVCPPShellApp::CVCPPShellApp()
- {
- }
-
- //===========================================================================
- // CLASS: CVCPPShellApp FUNCTION: InitInstance()
- //---------------------------------------------------------------------------
- // Note: This function was built by the MFC AppWizard.
- //===========================================================================
- BOOL CVCPPShellApp::InitInstance()
- {
- // Standard initialization
- // If you are not using these features and wish to reduce the size
- // of your final executable, you should remove from the following
- // the specific initialization routines you do not need.
-
- CVCPPShellDlg dlg;
- m_pMainWnd = &dlg;
- int nResponse = dlg.DoModal();
- if (nResponse == IDOK)
- {
- // Place code here to handle when the dialog is
- // dismissed with OK
- }
- else if (nResponse == IDCANCEL)
- {
- // Place code here to handle when the dialog is
- // dismissed with Cancel
- }
-
- // Since the dialog has been closed, return FALSE so that we exit the
- // application, rather than start the application's message pump.
- return FALSE;
- }
-
- //===========================================================================
- //===========================================================================
- // CLASS: CVCPPShellDlg
- //===========================================================================
- //===========================================================================
-
- //===========================================================================
- // CLASS: CVCPPShellDlg FUNCTION: <constructor>(CWnd*)
- //---------------------------------------------------------------------------
- // Note: This function was built by the MFC AppWizard.
- //===========================================================================
- CVCPPShellDlg::CVCPPShellDlg(CWnd* pParent /*=NULL*/)
- : CDialog(CVCPPShellDlg::IDD, pParent)
- {
- //{{AFX_DATA_INIT(CVCPPShellDlg)
-
- //}}AFX_DATA_INIT
- // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
- m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
-
- }
-
- //===========================================================================
- // CLASS: CVCPPShellDlg FUNCTION: DoDataExchange(CDataExchange*)
- //---------------------------------------------------------------------------
- // Note: This function was built by the MFC AppWizard.
- //===========================================================================
- void CVCPPShellDlg::DoDataExchange(CDataExchange* pDX)
- {
- CDialog::DoDataExchange(pDX);
- //{{AFX_DATA_MAP(CVCPPShellDlg)
- DDX_Text(pDX, IDC_TRAIN_NETWORK_REPORT, m_TrainNetwork_Report);
- //}}AFX_DATA_MAP
- }
-
-
- //===========================================================================
- // CLASS: CVCPPShellDlg FUNCTION: FillArrayFromFile(LPCTSTR, int, int)
- //===========================================================================
- float *CVCPPShellDlg::FillArrayFromFile(LPCTSTR fName, int numRows, int numCols)
- {
- CStdioFile fl;
- LPTSTR tmpBuffer = new char [250];
-
- char *token; //pointer to string tokens to extract from file strings
- char *delim = " ,\t\n"; //delimiter to use for string tokenizer
-
- //create array to hold floating values extracted from file
- long numCells = numRows * numCols;
- float *retArray = (float *)calloc (numCells, sizeof (float));
- int curIndx = 0;
-
- if (fl.Open(fName, CFile::modeRead))
- {
-
- //read file until end is reached
- while (((fl.ReadString(tmpBuffer, 250)) != NULL) && ((curIndx < numCells)))
- {
- //tokenize string to extract floating values as strings
- token = strtok (tmpBuffer, delim);
-
- while (token != NULL)
- {
- //convert token to float and store in array
- retArray[curIndx] = (float) atof (token);
- curIndx++;
-
- //tokenize string to extract floating values as strings
- token = strtok (NULL, delim);
-
- } //end token while
-
-
- } //end fl.Open while
-
- fl.Close();
- } //end if
-
- free (tmpBuffer);
-
- return retArray;
- } //end FillArrayFromFile
-
-
- //===========================================================================
- // CLASS: CVCPPShellDlg MESSAGE MAP
- //---------------------------------------------------------------------------
- // Note: This mapping was built by the MFC AppWizard.
- //===========================================================================
- BEGIN_MESSAGE_MAP(CVCPPShellDlg, CDialog)
- //{{AFX_MSG_MAP(CVCPPShellDlg)
- ON_WM_PAINT()
- ON_WM_QUERYDRAGICON()
- ON_BN_CLICKED(IDC_GET_NETWORK_OUTPUT, OnGetResponse)
- ON_BN_CLICKED(IDC_TRAIN_NETWORK, OnTrainNetwork)
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
-
-
- //===========================================================================
- // CLASS: CVCPPShellDlg FUNCTION: OnInitDialog()
- //---------------------------------------------------------------------------
- // Note: This function was built by the MFC AppWizard.
- //===========================================================================
- BOOL CVCPPShellDlg::OnInitDialog()
- {
-
- CDialog::OnInitDialog();
-
- // Set the icon for this dialog. The framework does this automatically
- // when the application's main window is not a dialog
- SetIcon(m_hIcon, TRUE); // Set big icon
- SetIcon(m_hIcon, FALSE); // Set small icon
-
- //dispaly initial message in Get Network Output Report edit box
- CEdit *pGetNetworkOutputReportEditBox = (CEdit *) GetDlgItem (IDC_GET_NETWORK_OUTPUT_REPORT);
- pGetNetworkOutputReportEditBox->SetWindowText(_T("Not tested."));
-
- //disables training if the DLL only supports a recall network
- if (RECALL_ONLY_NETWORK)
- {
- //disable Train Network button
- CWnd *pTrainNetworkButton = (CWnd *) GetDlgItem (IDC_TRAIN_NETWORK);
- pTrainNetworkButton->EnableWindow(FALSE);
-
- //disable Reset Network Before Training check box
- CButton *pResetNetworkCheckBox = (CButton *) GetDlgItem (IDC_RESET_NETWORK);
- pResetNetworkCheckBox->EnableWindow(FALSE);
-
- //dispaly initial message in Train Network Report edit box
- CEdit *pTrainNetworkReportEditBox = (CEdit *) GetDlgItem (IDC_TRAIN_NETWORK_REPORT);
- pTrainNetworkReportEditBox->SetWindowText(_T("Only Recall DLL Supported."));
-
- m_TrainNetwork_Report = _T("Recall Network Only.");
- }
- else
- {
- //dispaly initial message in Train Network Report edit box
- CEdit *pTrainNetworkReportEditBox = (CEdit *) GetDlgItem (IDC_TRAIN_NETWORK_REPORT);
- pTrainNetworkReportEditBox->SetWindowText(_T("Not tested."));
-
- m_TrainNetwork_Report = _T("Not tested.");
- }
-
- return TRUE; // return TRUE unless you set the focus to a control
- }
-
- //===========================================================================
- // CLASS: CVCPPShellDlg FUNCTION: OnPaint()
- //---------------------------------------------------------------------------
- // Note: This function was built by the MFC AppWizard.
- //---------------------------------------------------------------------------
- // If you add a minimize button to your dialog, you will need the code below
- // to draw the icon. For MFC applications using the document/view model,
- // this is automatically done for you by the framework.
- //===========================================================================
- void CVCPPShellDlg::OnPaint()
- {
- if (IsIconic())
- {
- CPaintDC dc(this); // device context for painting
-
- SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
-
- // Center icon in client rectangle
- int cxIcon = GetSystemMetrics(SM_CXICON);
- int cyIcon = GetSystemMetrics(SM_CYICON);
- CRect rect;
- GetClientRect(&rect);
- int x = (rect.Width() - cxIcon + 1) / 2;
- int y = (rect.Height() - cyIcon + 1) / 2;
-
- // Draw the icon
- dc.DrawIcon(x, y, m_hIcon);
- }
- else
- {
- CDialog::OnPaint();
- }
- }
-
- //===========================================================================
- // CLASS: CVCPPShellDlg FUNCTION: OnQueryDragIcon()
- //---------------------------------------------------------------------------
- // Note: This function was built by the MFC AppWizard.
- //---------------------------------------------------------------------------
- // The system calls this to obtain the cursor to display while the user drags
- // the minimized window.
- //===========================================================================
- HCURSOR CVCPPShellDlg::OnQueryDragIcon()
- {
- return (HCURSOR) m_hIcon;
- }
-
- //===========================================================================
- // CLASS: CVCPPShellDlg FUNCTION: OnGetResponse()
- //---------------------------------------------------------------------------
- // This function illustrates how the DLL generated by the Custom Solution
- // Wizard can be used for getting the network response (output).
- // Step by step instructions are given on how to use the generated DLL
- // for this purpose. Read through comments carefully performing all of the
- // REQUIRED ACTIONs as you get to them.
- //===========================================================================
- void CVCPPShellDlg::OnGetResponse()
- {
- //---------------------------------------------------------------------------
- // Step 1: Create an instance of NSRecallNetwork.
- //---------------------------------------------------------------------------
- // IMPLEMENTATION NOTES: The DLL_PATH_NAME is defined in Globals.h
- //---------------------------------------------------------------------------
- // Following this call, IsInitialized() should return true.
- // If IsInitialized() is false, check to make sure the path to the DLL is correct.
- //---------------------------------------------------------------------------
- // You could create an NSLearningNetwork object instead, if you have the
- // Developers level of the Custom Solution Wizard and used it along with a
- // NeuroSolutions breadboard capable of learning to generate the DLL.
- // Both NSRecallNetwork and NSLearningNetwork support recall operations.
- //---------------------------------------------------------------------------
- NSRecallNetwork nn(DLL_PATH_NAME);
-
- if (nn.IsInitialized())
- {
- //---------------------------------------------------------------------------
- // Step 2: Get the size of the DLL (number of inputs and outputs)
- //---------------------------------------------------------------------------
- int inputs;
- int outputs;
- nn.GetInputOutputInfo(inputs,outputs);
-
- //---------------------------------------------------------------------------
- // Step 3: Load the initial network weights.
- //---------------------------------------------------------------------------
- // IMPLEMENTATION NOTES: The BEST_WEIGHTS_PATH_NAME is defined in Globals.h.
- // The initial best weights file is an exact copy of the weights file that was
- // saved when the DLL was generated. However, the best weights file will change
- // with each run of the TrainNetwork function if the network is reset before
- // training.
- //---------------------------------------------------------------------------
- nn.LoadWeights(BEST_WEIGHTS_PATH_NAME);
-
- //---------------------------------------------------------------------------
- // Step 4: Define the input data.
- //---------------------------------------------------------------------------
- // IMPLEMENTATION NOTES: The following loads the training input data from your initial
- // network configuration into the array inputData.
- // Note that the number of inputs in the input data must match the number of inputs
- // expected by the generated DLL. Also, there can be any number of exemplars in the
- // input data as long as the number of exemplars in the input data matches the number
- // of exemplars in the desired data. In this case, NUMBER_OF_EXEMPLARS is defined in
- // Globals.h.
- //---------------------------------------------------------------------------
- float *inputData = FillArrayFromFile(INPUT_FILE_PATH_NAME, inputs, NUMBER_OF_EXEMPLARS);
-
- //---------------------------------------------------------------------------
- // Step 5: Declare the storage for the response.
- //---------------------------------------------------------------------------
- // IMPLEMENTATION NOTES : The dimensions of the outputData array have been set
- // to match the expected size of the output data.
- //---------------------------------------------------------------------------
- // Note: The first dimension of the outputData array is sized according
- // to the number of outputs in the DLL. The second dimension of the outputData
- // array is sized according to the number of exemplars in your data set as
- // defined in Globals.h.
- //---------------------------------------------------------------------------
- float *outputData = (float *) calloc (outputs * NUMBER_OF_EXEMPLARS, sizeof (float));
-
- //---------------------------------------------------------------------------
- // Step 6: Get the network response to the input data.
- //---------------------------------------------------------------------------
- // IMPLEMENTATION NOTES: NUMBER_OF_EXEMPLARS is defined in Globals.h.
- //---------------------------------------------------------------------------
- nn.GetResponse(NUMBER_OF_EXEMPLARS, inputData, outputData);
-
- //---------------------------------------------------------------------------
- // Step 7: Verify the results. (Optional)
- //---------------------------------------------------------------------------
- // IMPLEMENTATION NOTES: Outputs the results to the Get Network Output Report edit box
- //---------------------------------------------------------------------------
- // Prepare edit box for output -> clear its contents.
- CEdit *pGetNetworkOutputReportEditBox = (CEdit *) GetDlgItem (IDC_GET_NETWORK_OUTPUT_REPORT);
- pGetNetworkOutputReportEditBox->SetWindowText(_T(""));
-
- CString outStr = "Exemplar #\t";
-
- // Add labels to top of edit box
- for (int i = 1; i <= outputs; i++)
- {
- CString iAsStr;
- iAsStr.Format ("%d \t", i);
- outStr += "Output" + iAsStr;
- }
- outStr += "\r\n";
-
- // Show outputs for all up to 1000 exemplars
- int maxExemplars = (NUMBER_OF_EXEMPLARS > 1000)?1000:NUMBER_OF_EXEMPLARS;
- for (int j = 0; j < maxExemplars; j++)
- {
- CString jAsStr;
- jAsStr.Format("%d\t\t", j + 1);
- outStr += jAsStr;
-
- for (int k = 0; k < outputs; k++)
- {
- CString resultAsString;
- resultAsString.Format("%9f\t", outputData[(j * outputs) + k]);
- outStr += resultAsString;
- } //end for j
-
- outStr += "\r\n";
- } //end for i
-
-
- pGetNetworkOutputReportEditBox->SetWindowText(_T(outStr));
-
- //---------------------------------------------------------------------------
- // Perform some memory clean-up
- //---------------------------------------------------------------------------
- free (inputData);
- free (outputData);
-
- }
- //---------------------------------------------------------------------------
- // If initialization failed, report any errors here.
- //---------------------------------------------------------------------------
- else
- {
- //prepare edit box for output -> reset its contents
- CEdit *pGetNetworkOutputReportEditBox = (CEdit *) GetDlgItem (IDC_GET_NETWORK_OUTPUT_REPORT);
- pGetNetworkOutputReportEditBox->SetWindowText(_T("DLL Load Failed."));
- }
-
- //---------------------------------------------------------------------------
- // Update the dialog.
- //---------------------------------------------------------------------------
- UpdateData(FALSE);
- }
-
- //===========================================================================
- // CLASS: CVCPPShellDlg FUNCTION: OnTrainNetwork()
- //---------------------------------------------------------------------------
- // The function trains a learning network DLL and saves the best weights
- // to a specified file for later use.
- // Step by step instructions are given on how to use the generated DLL
- // for this purpose. Read through comments carefully. The IMPLEMENTATION NOTES
- // highlight parameters that you may wish to change in the future.
- //---------------------------------------------------------------------------
- // NOTE: This subroutine only applys to users of the Developers level of the
- // Custom Solution Wizard. The Developers level allows the user to generate
- // learning DLLs, whereas all other levels can only generate recall DLLs.
- //===========================================================================
- void CVCPPShellDlg::OnTrainNetwork()
- {
-
- //---------------------------------------------------------------------------
- // Update Train Network Report edit box to indicate that the network is training.
- //---------------------------------------------------------------------------
- CEdit *pTrainNetworkReportEditBox = (CEdit *) GetDlgItem (IDC_TRAIN_NETWORK_REPORT);
- pTrainNetworkReportEditBox->SetSel(0, -1, FALSE);
- pTrainNetworkReportEditBox->ReplaceSel("Training...", FALSE);
-
- //---------------------------------------------------------------------------
- // Step 1: Create an instance of NSLearningNetwork.
- //---------------------------------------------------------------------------
- // IMPLEMENTATION NOTES: The path of the DLL is defined in Globals.h.
- //---------------------------------------------------------------------------
- // Following this call, IsInitialized() should return true.
- // If IsInitialized() is false, one of the following errors occured:
- // * The path to the DLL is incorrect. IsLoaded() will be false.
- // * The path points a recall DLL. IsLoaded() will be true.
- //---------------------------------------------------------------------------
- // Note: This step will fail if you are not using the Developers level of
- // the Custom Solution Wizard or if you generated the DLL using a recall
- // NeuroSolutions breadboard.
- //---------------------------------------------------------------------------
- NSLearningNetwork nn(DLL_PATH_NAME);
-
- if (nn.IsInitialized())
- {
- //---------------------------------------------------------------------------
- // Step 2: Get the size of the DLL (number of inputs and outputs)
- //---------------------------------------------------------------------------
- int inputs;
- int outputs;
- nn.GetInputOutputInfo(inputs,outputs);
-
- //---------------------------------------------------------------------------
- // Step 3: Load the initial network weights. (Optional)
- //---------------------------------------------------------------------------
- // IMPLEMENTATION NOTES: The WEIGHTS_PATH_NAME has been defined in Globals.h to
- // reflect that of the weights file that was saved when the DLL was generated.
- //---------------------------------------------------------------------------
- // Note: This step is not necessary. If this step is not performed, the
- // network will simply start with random initial weights.
- //---------------------------------------------------------------------------
- nn.LoadWeights(WEIGHTS_PATH_NAME);
-
- //---------------------------------------------------------------------------
- // Resets the network (randomizes the network weights, etc.) if the user has so
- // indicated by checking the "Reset Network Before Training" check box
- //---------------------------------------------------------------------------
- CButton *pResetNetworkCheckBox = (CButton *) GetDlgItem (IDC_RESET_NETWORK);
- if (pResetNetworkCheckBox->GetCheck() == 1)
- nn.ResetNetwork();
-
- //---------------------------------------------------------------------------
- // Step 4: Define the input data.
- //---------------------------------------------------------------------------
- // IMPLEMENTATION NOTES: The following loads the training input data from your initial
- // network configuration into the array inputData.
- // Note that the number of inputs in the input data must match the number of inputs
- // expected by the generated DLL. Also, there can be any number of exemplars in the
- // input data as long as the number of exemplars in the input data matches the number
- // of exemplars in the desired data. In this case, NUMBER_OF_EXEMPLARS is defined in
- // Globals.h.
- //---------------------------------------------------------------------------
- float *inputData = FillArrayFromFile(INPUT_FILE_PATH_NAME, inputs, NUMBER_OF_EXEMPLARS);
-
- //---------------------------------------------------------------------------
- // Step 5: Define the desired data.
- //---------------------------------------------------------------------------
- // IMPLEMENTATION NOTES: The following loads the training desired data from your initial
- // network configuration into the array desiredData.
- // Note that the number of outputs in the desired data must match the number of outputs
- // expected by the generated DLL. Also, there can be any number of exemplars in the
- // desired data as long as the number of exemplars in the desired data matches the number
- // of exemplars in the input data. In this case, NUMBER_OF_EXEMPLARS is defined in
- // Globals.h.
- //---------------------------------------------------------------------------
- float *desiredData = FillArrayFromFile(DESIRED_FILE_PATH_NAME, outputs, NUMBER_OF_EXEMPLARS);
-
- //---------------------------------------------------------------------------
- // Step 6: Enable the automatic saving of the best weights. (Optional)
- //---------------------------------------------------------------------------
- // Note: This step is not necessary. The default value of this property is
- // always False. Setting it to True will cause the best network weights to be
- // saved during training. If this property is set to True, be sure to call
- // SetBestWeightsPathName() to set a valid path for the best weights (See Step 7).
- //---------------------------------------------------------------------------
- nn.SetSaveBestWeightsEnabled(true);
-
- //---------------------------------------------------------------------------
- // Step 7: Set the path for saving the best weights. (Optional)
- //---------------------------------------------------------------------------
- // IMPLEMENTATION NOTES : The BEST_WEIGHTS_PATH_NAME is defined in Globals.h.
- //---------------------------------------------------------------------------
- // Note: The specified path will be used for saving the best weights during
- // training. This SetBestWeightsPathName() function must be set to a
- // valid path if SetSaveBestWeightsEnabled() has been set to true. Otherwise,
- // setting this property is optional.
- //---------------------------------------------------------------------------
- nn.SetBestWeightsPathName(BEST_WEIGHTS_PATH_NAME);
-
- //---------------------------------------------------------------------------
- // Step 8: Train the network.
- //---------------------------------------------------------------------------
- // IMPLEMENTATION NOTES : The NUMBER_OF_EPOCHS and NUMBER_OF_EXEMPLARS are defined
- // in Globals.h and have been determined from the initial network configuration.
- //---------------------------------------------------------------------------
- // Note: Two versions of the Train() function are provided. This version does
- // not include cross validation parameters. If cross validation is desired,
- // use the other version of Train() and call SetCrossValidationEnabled(true).
- //---------------------------------------------------------------------------
- nn.Train(NUMBER_OF_EPOCHS, NUMBER_OF_EXEMPLARS, inputData, desiredData);
-
- //---------------------------------------------------------------------------
- // Step 9: Report best cost. (Optional)
- //---------------------------------------------------------------------------
- // This dialog-based application reports the best cost to the user.
- //---------------------------------------------------------------------------
- // Note: This step is not necessary, it is provided only to show how the best
- // cost can be obtained.
- //---------------------------------------------------------------------------
- float bestCost = nn.GetBestCost();
- m_TrainNetwork_Report.Format("Best Cost = %g",bestCost);
-
- //---------------------------------------------------------------------------
- // Perform some memory clean-up
- //---------------------------------------------------------------------------
- free (inputData);
- free (desiredData);
- }
-
- //---------------------------------------------------------------------------
- // If initialization failed, report any errors here.
- //---------------------------------------------------------------------------
- else
- {
- //---------------------------------------------------------------------------
- // If the DLL was loaded, this is probably a recall-only network.
- //---------------------------------------------------------------------------
- if (nn.IsLoaded())
- {
- m_TrainNetwork_Report = "DLL recall only.";
- }
- //---------------------------------------------------------------------------
- // Else, the DLL was not loaded, the path is probably incorrect.
- //---------------------------------------------------------------------------
- else
- {
- m_TrainNetwork_Report = "DLL load failed.";
- }
- }
-
- //---------------------------------------------------------------------------
- // Update the dialog.
- //---------------------------------------------------------------------------
- UpdateData(FALSE);
- }
-
-